//游戏控制逻辑
export class GameCon{
  //游戏格子
  gameArr: number[][]=[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
  isGameOver:boolean=false
  //初始化游戏分数
  score: number = 0;
  //init 方法用于初始化游戏状态。
  init(gameArr:number[]){
    for(let i=0;i<4;i++){
      for(let j=0;j<4;j++){
        this.gameArr[i][j]=gameArr[i*4+j]
      }
    }
    this.isGameOver=false
    //填充两个随机的非零数字到空白的格子中
    this.fillOneEmptyGame()
    this.fillOneEmptyGame()
  }
  //找到可以用于生成新数字的单元格，并生成新的数字进行填充
  fillOneEmptyGame() {
    let gameIndex= this.findOneEmptyGame()
    if(gameIndex!=-1){
      //转换为行号和列号
      let row = Math.floor(gameIndex/4)
      let col = gameIndex%4
      this.gameArr[row][col]=this.getRandomValue()
    }
  }
  //用于查找游戏数组中的空格子，并返回一个包含空格子索引的数组。
  findOneEmptyGame(){
    let games = []
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (!this.gameArr[i][j]) {
          games.push(i * 4 + j)
        }
      }
  }
    if (games.length) {
      return games[this.randomVal(games.length)]
    } else {
      return -1
    }
  }
  //生成新的数字，并且设置生成概率
  getRandomValue(){
    let rand= this.randomVal(100);
    var value =2;
    if(rand<=1){
      value = 8;
    }else if (rand<11){value=4;}
    return value;
  }
  //生成指定范围内的随机整数
  randomVal(max: number) {
    return Math.floor(Math.random() * max)
  }
  /*
       判断是否还可以移动。
       1、当前单元格是否为0；
       2、当前单元格和右侧单元格是否相等；
       3、当前单元格和下方单元格是否相等。
       */
  canMove(){
    //遍历二维数组
    for(let i=0; i<4;i++){
      for(let j=0;j<4;j++){
        let game= this.gameArr[i][j]
        if(game){
          //和右边比较，是否相等
          if (j<3 &&this.gameArr[i][j] == this.gameArr[i][j+1]) {
            return true
          }
          //和下方比较
          if (i<3&&this.gameArr[i][j] == this.gameArr[i+1][j]) {
            return true
          }
        }else {
          return true
        }
      }
    }
    return false
  }

//将二维数组转为一维数组
  getFlatGameArr(){
    var flatCellArr =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        flatCellArr[i * 4+j] = this.gameArr[i][j]
      }
    }
    return flatCellArr
  }
  //将单元格数向左或向右移动，移除0并对相邻相同数进行叠加,toLeft表示是否向左
    MoveCells(toLeft:boolean){
      for(let i=0;i<4;i++){
        let newArr= Array(4).fill(0)
        for(let j =0 ; j<4;j++){
          newArr[j]=this.gameArr[i][j]
        }
        let resultArr=this.removeAndAdd(newArr,toLeft)
        for(let j=0;j<4;j++){
          this.gameArr[i][j] = resultArr[j]
        }
      }
    }
// 将单元格数向下或向上移动，移除0并对相邻相同数进行叠加,toup表示是否向上
  varMoveCells(toUP:boolean){
    for(let i=0;i<4;i++){
      let newArr =Array(4).fill(8)
       for(let j =0 ; j<4;j++){
         newArr[j]=this.gameArr[j][i]
       }
      let resultArr=this.removeAndAdd(newArr,toUP)
      for(let j=0;j<4;j++){
        this.gameArr[j][i]=resultArr[j]
      }
    }

  }

  /**
   * 1、去掉数组中的0，向头或向尾压缩数组。
   * 0,4,0,4向左压缩变成：4,4,0,0. 向右压缩变成：0,0,4,4
   * 2、相邻的数如果相同，则进行相加运算。
   * 4,4,0,0向左叠加变成：8,0,0,0. 向右叠加变成：0,0,0,8
   * toHead表示是否是头压缩
   */
  removeAndAdd(arr:number[],toHead:boolean){
    // 创建一个新数组，用于存储处理后的结果
      let newArr=Array(4).fill(0);
    // 过滤掉输入数组中的所有零元素
    let arrWithoutZero=arr.filter((x) =>x!==0);
    // 如果没有非零元素，则直接返回新数组
    if(arrWithoutZero.length==0){
      return newArr;
    }
    // 根据移动方向的不同，分别处理新数组的填充和相邻相同数字的合并操作
    if(toHead){
      // 向头部移动时，从头开始填充新数组，并在遇到相邻相同数字时进行合并操作
      for(let i=0;i<arrWithoutZero.length;i++){
        newArr[i]=arrWithoutZero[i];
      }
      for(let j=0;j<newArr.length-1;j++){
        if(newArr[3-j] === newArr[2-j]&&newArr[3-j]!==0){
          // 如果当前数字与前一个数字相同且不为零，则进行合并操作
          newArr[3-j]=0;
          newArr[2-j] *=2;
        }
      }
    }else {
      // 向尾部移动时，从尾部开始填充新数组，并在遇到相邻相同数字时进行合并操作
      for(let i=0;i<arrWithoutZero.length;i++){
        newArr[newArr.length-i-1]=arrWithoutZero[arrWithoutZero.length-i-1];
      }
      for(let j=0;j<newArr.length;j++){
          if(newArr[j] === newArr[j+1]&&newArr[j]!==0){
            // 如果当前数字与后一个数字相同且不为零，则进行合并操作
            newArr[j]=0;
            newArr[j+1]*=2;
          }
      }
    }
      return newArr;
  }
  //检查游戏是否结束或者是否可以继续进行下一步操作
  checkGameOverOrContinue(){
    // 首先检查游戏是否可以继续进行，即是否还有空的单元格或者相邻单元格有相同数字可以合并
    if(this.canMove()){
      // 如果可以继续进行，则在空的单元格中填充一个新的数字
      this.fillOneEmptyGame();
    }else {
      //游戏结束
      this.isGameOver=true;
    }

  }
  moveUp(){
    this.varMoveCells(true)
    this.checkGameOverOrContinue()
  }
  moveDown(){
    this.varMoveCells(false)
    this.checkGameOverOrContinue()
  }
  moveLeft(){
    this.MoveCells(true)
    this.checkGameOverOrContinue()
  }
  moveRight(){
    this.MoveCells(false)
    this.checkGameOverOrContinue()
  }

  //更新游戏分数
  UpdateScore(merged: boolean){
    if(merged){
      this.score++;
      //更新分数
      //this.index.updateCells();
    }
  }















}